import { createApp } from '/scripts/vue.esm-browser.prod.min.js'

app = createApp
  data: =>
    formal: no
    gender: 'm'
    history: []
    initialScene: null
    name: ''
    reader: new FileReader()
    scene: null
    showHistory: no
    swtches: new Map()
  methods:
    parseSwtches: (text) ->
      swtches = while match = text.match /^([+-])([\p{L}\d_]+) (.*)/u
        text = match[3]
        {value: match[1] == '+', name: match[2]}
      {text, swtches}
    loadStory: (story, version = 0) ->
      paragraphs = story.split('\n\n')
      scenes = new Map paragraphs.map (paragraph) =>
        [title, description, options...] = paragraph.split('\n').filter((line) => line)
        scene =
          title: title
          description: if version >= 1 then this.parseSwtches(description) else {text: description, swtches: []}
          options: options.map (option) =>
            [left, right] = option.split(' > ')
            {text, swtches: prerequisites} = this.parseSwtches(left)
            {text: next, swtches: consequences} = this.parseSwtches(right)
            {prerequisites, text, next, consequences}
        [title, scene]
      scenes.forEach (scene) =>
        scene.options.forEach (option) =>
          option.next = scenes.get option.next
          throw "Neexistující scéna: #{option.next}" if not option.next?
      this.initialScene = scenes.get story.match(/.*/)[0]
    loadStoryFromFile: (file) ->
      [_, this.name, version] = file.name.match /^(.*)\.iprib(\d+)$/
      version = parseInt version
      this.reader.onload = (event) => this.loadStory(event.target.result, version)
      this.reader.readAsText file
    triggerSwtches: (swtches) ->
      swtches.forEach (swtch) =>
        this.swtches.set(swtch.name, swtch.value)
    enterScene: (scene) ->
      this.triggerSwtches scene.description.swtches
      this.scene = scene
    optionLegal: (option) ->
      option.prerequisites.every (swtch) =>
        swtch.value == (this.swtches.get(swtch.name) ? no)
    triggerOption: (option) ->
      if this.showHistory
        this.history.push this.interpolate this.scene.description.text
        this.history.push this.interpolate option.text
      this.triggerSwtches option.consequences
      this.enterScene option.next
    interpolate: (text) ->
      loop
        last = text
        text = text
          .replaceAll(/\[([^/|\]}]*)\/([^/|\]}]*)\]/g, (_, masculine, feminine) => if this.gender == 'f' then feminine else masculine)
          .replaceAll(/\[([^/|\]}]*)\|([^/|\]}]*)\]/g, (_, informal, formal) => if this.formal then formal else informal)
          .replaceAll(/\{([^/|\]}]*)\|([^/|\]}]*)\/([^/|\]}]*)\}/g, (_, condition, ifTrue, ifFalse) => if this.swtches.get(condition) then ifTrue else ifFalse)
        return text if text == last
    startStory: ->
      this.enterScene this.initialScene
    endStory: ->
      if this.scene.options.length == 0 or confirm "Skutečně chcete příběh ukončit? Smaže se tím všechen postup."
        this.scene = null
        this.swtches = new Map()
        this.history = []

window.vm = app.mount '#app'
